package com.usian.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import com.usian.admin.mapper.AdUserMapper;
import com.usian.admin.service.AdUserLoginService;
import com.usian.common.exception.code.AdminStatusCode;
import com.usian.common.exception.CatchCustomException;
import com.usian.model.admin.dtos.AdUserDto;
import com.usian.model.admin.pojos.AdUser;
import com.usian.model.admin.vos.AdUserVo;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.user.common.AppJwtUtil;
import com.usian.user.common.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Service
@SuppressWarnings("ALL")
@Transactional(rollbackFor = {NullPointerException.class})
public class AdUserLoginServiceImpl extends ServiceImpl<AdUserMapper, AdUser> implements AdUserLoginService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 登录
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult login(AdUserDto dto) {
        //检查参数
        if (dto == null) {
            CatchCustomException.catchs(AdminStatusCode.PARAM_FAIL, "参数非法");
        }
        //判断用户名和密码
        if (StringUtils.isEmpty(dto.getName()) || StringUtils.isEmpty(dto.getPassword())) {
            CatchCustomException.catchs(AdminStatusCode.PARAM_FAIL, "参数非法");
        }
        //根据用户名查询
        AdUser adUser = this.getOne(new LambdaQueryWrapper<AdUser>().eq(AdUser::getName, dto.getName()));
        if (adUser == null) {
            CatchCustomException.catchs(AdminStatusCode.USERNAME_NULL, "用户名不正确");
        }
        //状态必须是可用状态  才允许登录
        if (adUser.getStatus() != 9) {
            CatchCustomException.catchs(AdminStatusCode.LOGIN_STATUS, "当前用户已被锁定，需要联系管理员");
        }
        //判断密码
        if (!BCrypt.checkpw(dto.getPassword(), adUser.getPassword())) {
            CatchCustomException.catchs(AdminStatusCode.PASSWORD_FAIL, "密码不正确");
        }
        //签发token
        String token = AppJwtUtil.getToken(Long.parseLong(adUser.getId() + ""));        //封装用户使用信息

        AdUserVo adUserVo = JSON.parseObject(JSON.toJSONString(adUser), AdUserVo.class);

        adUserVo.setToken(token);
        adUserVo.setPassword("");
        //连接数据库  修改最后一次登录时间
        adUser.setLoginTime(new Date());
        this.updateById(adUser);
        return ResponseResult.okResult(adUserVo);
    }

    /**
     * 导出
     *
     * @param response
     * @throws IOException
     */
    @Override
    public void export(HttpServletResponse response) throws IOException {
        //获取输出流
        ServletOutputStream outputStream = response.getOutputStream();
        response.setHeader("User表", "user");
        response.setContentType("text/csv");//内容类型
        CSVWriter csvWriter = new CSVWriter(new OutputStreamWriter(outputStream, "utf-8"));
        String[] strings = new String[]{"主键", "登录用户名", "登录密码", "盐", "昵称", "头像", "手机号", "状态", "邮箱", "最后一次登录时间", "创建时间"};
        csvWriter.writeNext(strings);
        //初始化为1
        int page = 1;
        while (true) {
            //每页2000条
            Page<AdUser> page1 = new Page<>(page, 2000);
            IPage<AdUser> iPage = this.page(page1);
            System.out.println("hhhhhh");
            //getRecords: 获取分页数据
            if (CollectionUtils.isEmpty(iPage.getRecords())) {
                break;

            }
            for (AdUser record : iPage.getRecords()) {
                csvWriter.writeNext(new String[]{
                        record.getId().toString(),
                        record.getName(),
                        record.getPassword(),
                        record.getSalt(),
                        record.getNickname(),
                        record.getImage(),
                        record.getPhone(),
                        String.valueOf(record.getStatus()),
                        record.getEmail(),
                        SimpleDateFormat.getDateInstance().format(record.getLoginTime()),
                        SimpleDateFormat.getDateInstance().format(record.getCreatedTime())
                });
            }
//            使当前页加加
            page++;
//            释放缓存，防止内存泄漏
            csvWriter.flush();
        }
//        关闭流
        csvWriter.close();
    }

    /**
     * 导入
     *
     * @param response
     * @throws Exception
     */
    @Override
    public void imports(HttpServletResponse response) throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
        //读取csv文件
        CSVReader csvReader = new CSVReader(new FileReader("E:\\exprot.csv"));
        //获取标题行
        String[] titles = csvReader.readNext();

//        csvReader.readAll();

        while (true) {
            AdUser adUser = new AdUser();
            String[] conent = csvReader.readNext();
            if (conent == null) {
                break;
            }
//            adUser.setId(Integer.parseInt(conent[0]));

            adUser.setName(conent[1]);
            adUser.setPassword(conent[2]);
            adUser.setSalt(conent[3]);
            adUser.setNickname(conent[4]);
            adUser.setImage(conent[5]);
            adUser.setPhone(conent[6]);
            adUser.setStatus(Integer.parseInt(conent[7]));
            adUser.setEmail(conent[8]);
            adUser.setLoginTime(simpleDateFormat.parse(conent[9]));
            adUser.setCreatedTime(simpleDateFormat.parse(conent[10]));
            System.out.println(adUser);

            //       添加到redis去重
            Long csv = stringRedisTemplate.opsForSet().add("CSV", JSON.toJSONString(adUser));
            if (csv == 0) {
                System.out.println("重复数据");
                continue;
            }
            //            根据id查询数据如果查到则退出循环不添加到数据库，如果为空则添加到数据库
            LambdaQueryWrapper<AdUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(AdUser::getName, adUser.getName());
            AdUser one = this.getOne(lambdaQueryWrapper);
            if (one != null) {
                continue;
            }
//            添加到数据库中
            this.save(adUser);
            System.out.println(adUser);
        }
    }


}
